from flask import Flask, jsonify, request
import time
import random
import requests
from skywalking import agent, config
import os

# 配置 SkyWalking 代理
config.init(
    agent_collector_backend_services=os.getenv('SW_AGENT_COLLECTOR_BACKEND_SERVICES', 'oap:11800'),
    agent_name=os.getenv('SW_AGENT_NAME', 'flask-demo-service'),
    agent_instance_name='flask-instance-1',
    agent_logging_level='INFO',
)
agent.start()

app = Flask(__name__)


# 模拟数据库操作
def mock_database_query():
    """模拟数据库查询"""
    time.sleep(random.uniform(0.1, 0.3))
    return {"status": "success", "data": f"query_result_{random.randint(1, 100)}"}


def mock_external_api_call():
    """模拟外部 API 调用"""
    time.sleep(random.uniform(0.2, 0.5))
    return {"status": "success", "message": "external_api_response"}


def mock_cache_operation():
    """模拟缓存操作"""
    time.sleep(random.uniform(0.05, 0.15))
    return {"status": "success", "cached": random.choice([True, False])}


@app.route('/')
def hello():
    """首页"""
    return jsonify({
        "message": "Welcome to Flask SkyWalking Demo!",
        "endpoints": [
            "/api/users",
            "/api/orders",
            "/api/products",
            "/api/performance",
            "/api/error-test"
        ]
    })


@app.route('/api/users')
def get_users():
    """获取用户列表 - 模拟复杂业务逻辑"""
    start_time = time.time()

    # 模拟多个操作
    db_result = mock_database_query()
    cache_result = mock_cache_operation()

    # 模拟一些业务逻辑
    time.sleep(random.uniform(0.1, 0.2))

    processing_time = round((time.time() - start_time) * 1000, 2)

    return jsonify({
        "endpoint": "/api/users",
        "users": [
            {"id": 1, "name": "Alice", "email": "alice@example.com"},
            {"id": 2, "name": "Bob", "email": "bob@example.com"},
            {"id": 3, "name": "Charlie", "email": "charlie@example.com"}
        ],
        "database": db_result,
        "cache": cache_result,
        "processing_time_ms": processing_time
    })


@app.route('/api/orders')
def get_orders():
    """获取订单列表 - 模拟外部 API 调用"""
    start_time = time.time()

    # 模拟多个操作
    db_result = mock_database_query()
    api_result = mock_external_api_call()
    cache_result = mock_cache_operation()

    processing_time = round((time.time() - start_time) * 1000, 2)

    return jsonify({
        "endpoint": "/api/orders",
        "orders": [
            {"id": 1001, "product": "Laptop", "status": "shipped"},
            {"id": 1002, "product": "Mouse", "status": "delivered"},
            {"id": 1003, "product": "Keyboard", "status": "processing"}
        ],
        "database": db_result,
        "external_api": api_result,
        "cache": cache_result,
        "processing_time_ms": processing_time
    })


@app.route('/api/products')
def get_products():
    """获取产品列表 - 模拟较慢的响应"""
    # 模拟慢查询
    time.sleep(random.uniform(0.5, 1.5))

    return jsonify({
        "endpoint": "/api/products",
        "products": [
            {"id": 1, "name": "Laptop", "price": 999.99, "category": "Electronics"},
            {"id": 2, "name": "Desk Chair", "price": 199.99, "category": "Furniture"},
            {"id": 3, "name": "Coffee Mug", "price": 12.99, "category": "Kitchen"}
        ]
    })


@app.route('/api/performance')
def performance_test():
    """性能测试端点 - 模拟不同响应时间"""
    delay = request.args.get('delay', default=0, type=float)
    operations = request.args.get('operations', default=1, type=int)

    if delay > 0:
        time.sleep(delay)

    results = []
    for i in range(operations):
        results.append({
            "operation": i + 1,
            "db_query": mock_database_query(),
            "cache_op": mock_cache_operation()
        })

    return jsonify({
        "endpoint": "/api/performance",
        "requested_delay": delay,
        "operations_count": operations,
        "results": results
    })


@app.route('/api/error-test')
def error_test():
    """错误测试端点 - 模拟各种错误"""
    error_type = request.args.get('type', 'not_found')

    if error_type == 'not_found':
        return jsonify({"error": "Resource not found"}), 404
    elif error_type == 'server_error':
        return jsonify({"error": "Internal server error"}), 500
    elif error_type == 'validation':
        return jsonify({"error": "Validation failed"}), 400
    elif error_type == 'exception':
        # 模拟未处理异常
        raise ValueError("This is a simulated exception")
    else:
        return jsonify({"error": "Unknown error type"}), 400


@app.route('/api/chain-call')
def chain_call():
    """链式调用测试 - 模拟微服务间的调用"""
    try:
        # 模拟调用其他服务
        response = requests.get('http://flask-app:5000/api/users', timeout=5)
        user_data = response.json()

        # 继续处理
        db_result = mock_database_query()

        return jsonify({
            "endpoint": "/api/chain-call",
            "user_service_response": user_data,
            "local_processing": db_result
        })
    except requests.exceptions.RequestException as e:
        return jsonify({"error": f"Service call failed: {str(e)}"}), 500


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=False)